<?php
/**
 * 作用：微信处理模块
 * 作者: shijy@soe-soe.com
 * 日期: 2016/4/27 15:41
 * 公司: 浙江宣逸网络科技有限公司<www.soe-soe.com>
 */
namespace Common\Model;
class WeixinModel extends BaseModel{

	//微信回复类型--暂时无用
	const REPLY_TYPE_BASIC 		= 'basic';//文本
	const REPLY_TYPE_COVER 		= 'cover';//
	const REPLY_TYPE_CUSTOM 	= 'custom';//
	const REPLY_TYPE_IMAGE 		= 'images';//图片
	const REPLY_TYPE_MUSIC 		= 'music';//音乐
	const REPLY_TYPE_NEWS 		= 'news';//图文
	const REPLY_TYPE_USERAPI 	= 'userapi';//
	const REPLY_TYPE_VIDEO 		= 'video';//视频
	const REPLY_TYPE_VOICE 		= 'voice';//语音
	const REPLY_TYPE_WXCARD 	= 'wxcard';//微信卡券
	const REPLY_TYPE_CARD 		= 'card';//自平台卡券

	//关键词匹配方式--暂时无用
	const MATCH_TYPE_STRICT			= 1;//完全匹配，
	const MATCH_TYPE_LIST			= 2;//关键字列表，
	const MATCH_TYPE_REGX			= 3;//正则;

	//微信消息类型，本地向微信发送消息时使用
	const WEIXIN_TYPE_TEXT 		= 'text';//文本
	const WEIXIN_TYPE_WXCARD 	= 'wxcard';//微信卡券
	const WEIXIN_TYPE_VIDEO 	= 'video';//视频
	const WEIXIN_TYPE_VOICE 	= 'voice';//语音
	const WEIXIN_TYPE_IMAGE 	= 'images';//图片
	const WEIXIN_TYPE_MUSIC 	= 'music';//音乐
	const WEIXIN_TYPE_NEWS 		= 'mpnews';//图文消息


	/**
	 * 获取文章列表数据，哪前只针对纯文字与新闻回复进行
	 * @param int $page
	 * @param int $pageSize
	 * @return array
	 */
	public static function getRuleList($page=1,$pageSize=10){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');

		$m=M("ims_rule_keyword",null,DB_MAIN_CFG);
		$where = ' type<>'.self::MATCH_TYPE_REGX;//排除正则


		$dataSuccess['total'] = $m->where($where)->count();//获取数据总条数
		$dataSuccess['page'] = max($page,1);//返回当前页
		$dataSuccess['totalPage'] = ceil($dataSuccess['total']/$pageSize);//总共页数
		$dataSuccess['nextPage'] = $dataSuccess['page'] >= $dataSuccess['totalPage'] ? 0 : 1;//是有有下一页
		$offset = ($dataSuccess['page']-1)*$pageSize;
		$list = $m->where($where)->limit($offset,$pageSize)->order(" displayorder DESC ")->select();

		$sub=array(
			WeixinModel::REPLY_TYPE_BASIC	=> array(),
			WeixinModel::REPLY_TYPE_NEWS	=> array()
		);

		$roleList=array();
		foreach($list as $item){
			$roleList[$item['id']]=$item;
			switch($item['module']){
				case WeixinModel::REPLY_TYPE_BASIC:
					$sub[WeixinModel::REPLY_TYPE_BASIC][]=$item['id'];
					break;
				case WeixinModel::REPLY_TYPE_NEWS:
					$sub[WeixinModel::REPLY_TYPE_NEWS][]=$item['id'];
					break;
			}
		}
		unset($list);
		if(count($sub[WeixinModel::REPLY_TYPE_BASIC])>0){
			$replyModule=WeixinModel::REPLY_TYPE_BASIC;
			$ruls	 = implode(',',$sub[$replyModule]);
			$subList = M('ims_reply_'.$replyModule,null,DB_MAIN_CFG)->where("rid in ({$ruls})")->select();
			foreach($subList as $one){
				$roleList[$one['rid']]['sub']=$one;
			}
		}

		if(count($sub[WeixinModel::REPLY_TYPE_NEWS])>0){
			$replyModule=WeixinModel::REPLY_TYPE_NEWS;
			$ruls	 = implode(',',$sub[$replyModule]);
			$subList = M('ims_reply_'.$replyModule,null,DB_MAIN_CFG)->where("rid in ({$ruls})")->select();
			foreach($subList as $one){
				$roleList[$one['rid']]['sub']=$one;
			}
		}


		$dataSuccess['data'] = $roleList;
		return $dataSuccess;
	}


	public static function deleteRule($ruleID){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		if(!$ruleID || $ruleID<1){
			$dataFailure['msg']='规则编号错误';
			return $dataFailure;
		}
		$ruleM=M('ims_rule_keyword',null,DB_MAIN_CFG);
		$module=$ruleM->where("id={$ruleID}")->getField('module');

		$result=$ruleM->where("id={$ruleID}")->delete();
		if($result===false){
			$dataFailure['msg']='规则删除失败';
			return $dataFailure;
		}

		M('ims_reply_'.$module,null,DB_MAIN_CFG)->where("rid={$ruleID}")->delete();

		return $dataSuccess;


	}



	/**
	 * 获取消息列表
	 * Author: shijy
	 * @param $page
	 * @param $pageSize
	 */
	public static function getMsgList($page,$pageSize,$keyword=null){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');

		$m=M("ims_stat_msg_history",null,DB_MAIN_CFG);
		$where='1';
		$dataSuccess['total'] = $m->where($where)->count();//获取数据总条数
		$dataSuccess['page'] = max($page,1);//返回当前页
		$dataSuccess['totalPage'] = ceil($dataSuccess['total']/$pageSize);//总共页数
		$dataSuccess['nextPage'] = $dataSuccess['page'] >= $dataSuccess['totalPage'] ? 0 : 1;//是有有下一页
		$offset = ($dataSuccess['page']-1)*$pageSize;
		$list = $m->where($where)->limit($offset,$pageSize)->order(" displayorder DESC ")->select();

	}


//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////


	/**
	 * 获取微信通信用的token
	 * Author: shijy
	 * @return mixed
	 */
	public static function getAccessToken($company=JINGDE){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');


		switch ($company){
			case JINGDE:
				$appid='wxe8d99f915b095008';
				$timestamp=time();
				$key='s5vgm@sLuXaaXMooNYx#BgSHw1r7hNBm';
				$sign=md5($appid.$timestamp.$key);
				$curlGet="http://wx.zqgame.com/addons/zqgame/buildtoken.php?appid={$appid}&timestamp={$timestamp}&sign={$sign}";

				$ch = curl_init(); //初始化一个CURL对象
				curl_setopt($ch, CURLOPT_URL, $curlGet);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
				curl_setopt($ch, CURLOPT_POST, 0);
				$data = curl_exec($ch);
				$data = json_decode($data, true);
				curl_close($ch);
				if (is_array($data)) {
					if ($data['errcode'] != 0) {
						$dataFailure['msg'] = $data['errmsg'];
						return $dataFailure;
					}
					$data['deadline'] = $data['expires_in'];//为了提前刷新
				} else {
					return $dataFailure;
				}
				S('WX_ACCESS_TOKEN'.$company, serialize($data));
				$dataSuccess['data'] = array(
					'appId' => $appid,
					'access_token' => $data['access_token']
				);
				return $dataSuccess;
			case COMPANY_KNB:
			case COMPANY_CSMF:
				return self::getAccessToken_knb_csmf($company);
				break;
			case COMPANY_CHENSU:
				do {
					//辰速汽车后市场
					$appid = "wxd83b527cb7caf5ef";
					$AppSecret = "8d748ac890d7d0c871194b2a38098b16";

					$data = unserialize(S('WX_ACCESS_TOKEN'.$company));
					$now = time();
					if ($data && $data['deadline'] > $now) {
						$dataSuccess['data'] = array(
							'appId' => $appid,
							'access_token' => $data['access_token']
						);
						return $dataSuccess;
					}

					$curlGet = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$AppSecret}";
					$ch = curl_init(); //初始化一个CURL对象
					curl_setopt($ch, CURLOPT_URL, $curlGet);
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
					curl_setopt($ch, CURLOPT_POST, 0);
					$data = curl_exec($ch);
					$data = json_decode($data, true);
					curl_close($ch);
					if (is_array($data)) {
						if ($data['errcode'] != 0) {
							$dataFailure['msg'] = $data['errmsg'];
							return $dataFailure;
						}
						$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
					} else {
						return $dataFailure;
					}
					S('WX_ACCESS_TOKEN'.$company, serialize($data));
					$dataSuccess['data'] = array(
						'appId' => $appid,
						'access_token' => $data['access_token']
					);
					return $dataSuccess;
				}while(false);
				break;
			default:
				$data=unserialize(S('WX_ACCESS_TOKEN_JCH'.$company));
				$now=time();
				if( false && $data && $data['deadline']>$now){
					$dataSuccess['data']=array(
						'appId'			=> $data['appId'],
						'access_token'	=> $data['access_token']
					);
					return $dataSuccess;
				}

				$ret=UtilsModel::broadcast('get_token',null,'jch');

				$dataSuccess['data']['appId']=$ret['data']['appid'];
				$dataSuccess['data']['access_token']=$ret['data']['access_token'];
				$dataSuccess['data']['timestamp']=$ret['data']['timestamp'];

				$data=array(
					'appId'=>$dataSuccess['data']['appId'],
					'access_token'=>$dataSuccess['data']['access_token'],
					'deadline'=>$dataSuccess['data']['timestamp']
				);
				S('WX_ACCESS_TOKEN_JCH'.$company,serialize($data));
				return $dataSuccess;
				break;
		}
	}


	/**
	 * 获取外部的access_token,比如看宁波
	 * Author: shijy
	 * @return array
	 */
	public static function getAccessToken_knb_csmf($company=CURRENT_COMPANY){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');


		$data=unserialize(S('WX_ACCESS_TOKEN_OUTER'.$company));
		$now=time();
		if(false && $data && $data['deadline']>$now){
			$dataSuccess['data']=array(
				'appId'			=> $data['appId'],
				'access_token'	=> $data['access_token']
			);
			return $dataSuccess;
		}

		// access_token 应该全局存储与更新，以下代码以写入到文件中做示例
		if($company==COMPANY_KNB){
			$kannbJSsdk=file_get_contents(WECHAT_OUTER_ACCESS_TOKEN_URI_KNB);
		}else{
			$kannbJSsdk=file_get_contents(WECHAT_OUTER_ACCESS_TOKEN_URI_CSMF);
		}


		$signPackage=json_decode($kannbJSsdk,1);

		$data=array(
			'appId'=>$signPackage['data']['appId'],
			'access_token'=>$signPackage['data']['access_token'],
			'deadline'=>$signPackage['data']['expire']
		);
		S('WX_ACCESS_TOKEN_OUTER'.$company,serialize($data));
		$dataSuccess['data']=array(
			'appId'			=> $data['appId'],
			'access_token'	=> $data['access_token']
		);
		return $dataSuccess;
	}
	

	/**
	 * 获取jsapiTicket
	 * Author: shijy
	 * @param $access_token
	 * @return array
	 */
	public static function getJsApiTicket($access_token=null,$company=CURRENT_COMPANY){
			$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
			$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');
			$data = unserialize(S('WX_JSAPI_TICKET'.$company));

			$now = time();
			if ( false && $data && $data['deadline'] > $now) {
				$dataSuccess['data'] = array(
					'appId'=>$data['appId'],
					'ticket' => $data['ticket']
				);
				return $dataSuccess;
			}

			$appID		= 0;
			if (!$access_token){
				$ret=self::getAccessToken($company);
				if($ret['status']!=0){
					return $ret;
				}
				$access_token	= $ret['data']['access_token'];
				$appID			= $ret['data']['appId'];
			}


			$curlGet = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$access_token}";
			$ch = curl_init(); //初始化一个CURL对象
			curl_setopt($ch, CURLOPT_URL, $curlGet);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_POST, 0);
			$data = curl_exec($ch);
			$data = json_decode($data, true);
			curl_close($ch);


			if (is_array($data)) {
				if ($data['errcode'] != 0) {
					$dataFailure['msg'] = $data['errmsg'];
					return $dataFailure;
				}
				$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
			} else {
				return $dataFailure;
			}
			$data['appId'] = $appID;
			S('WX_JSAPI_TICKET'.$company, serialize($data));
			$dataSuccess['data'] = array(
				'appId' => $appID,
				'ticket' => $data['ticket']
			);
			return $dataSuccess;
	}

	/**
	 * 获取卡券的api_ticket
	 * Author: shijy
	 */
	public static function getCardApiTicket($access_token=null){
		$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
		$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');
		$data = unserialize(S('WX_CARDAPI_TICKET'));

		$now = time();
		if ($data && $data['deadline'] > $now) {
			$dataSuccess['data'] = array(
				'appId'=>$data['appId'],
				'ticket' => $data['ticket']
			);
			return $dataSuccess;
		}

		$appID		= 0;
		if (!$access_token){
			$ret=self::getAccessToken();
			if($ret['status']!=0){
				return $ret;
			}
			$access_token	= $ret['data']['access_token'];
			$appID			= $ret['data']['appId'];
		}

		$curlGet = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=wx_card";
		$ch = curl_init(); //初始化一个CURL对象
		curl_setopt($ch, CURLOPT_URL, $curlGet);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 0);
		$data = curl_exec($ch);
		$data = json_decode($data, true);
		curl_close($ch);


		if (is_array($data)) {
			if ($data['errcode'] != 0) {
				$dataFailure['msg'] = $data['errmsg'];
				return $dataFailure;
			}
			$data['deadline'] = $now + $data['expires_in'] - 5;//为了提前刷新
		} else {
			return $dataFailure;
		}
		$data['appId'] = $appID;
		S('WX_CARDAPI_TICKET', serialize($data));
		$dataSuccess['data'] = array(
			'appId' => $appID,
			'ticket' => $data['ticket']
		);
		return $dataSuccess;
	}

	/**
	 * 微信分享获取signPackage
	 * Author: shijy
	 * @return array
	 */
	public static function getSignPackage($company = CURRENT_COMPANY){
		$ret = self::getJsApiTicket(null,$company);

		if($ret['status']!=0){
			return $ret;
		}

		$dataSuccess = array('status' => self::SUCCESS, 'msg' => '成功');
		$dataFailure = array('status' => self::FAILURE, 'msg' => '无效参数');


		$jsapiTicket=$ret['data']['ticket'];
		$appId=$ret['data']['appId'];
		// 注意 URL 一定要动态获取，不能 hardcode.
		
		$domain=UtilsModel::getFullDomain();
		$url = "{$domain}{$_SERVER[REQUEST_URI]}";

		$timestamp = time();
		$nonceStr = self::createNonceStr();


		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";

		$signature = sha1($string);

		$signPackage = array(
			"appId"     => $appId,
			"nonceStr"  => $nonceStr,
			"timestamp" => $timestamp,
			"url"       => $url,
			"signature" => $signature,
			"rawString" => $string
		);
		$dataSuccess['data']=$signPackage;
		return $dataSuccess;
	}


	/**
	 * 创建随机字符串
	 * Author: shijy
	 * @param int $length
	 * @return string
	 */
	private static function createNonceStr($length = 16) {
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}
	
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////

	/**
	 * 微信专用请求函数
	 * Author: shijy
	 * @param $url
	 * @param $content
	 * @return array|mixed
	 */
	public static function send($url,$content){
		$getToken=self::getAccessToken();
		if($getToken['status']!=0){
			return $getToken;
		}


		$access_token=$getToken['data']['access_token'];
		
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');

		$url=$url.$access_token;

		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
		$data = curl_exec($ch);

		$data=json_decode($data,true);
		if($data['errcode']!=0){
			$dataFailure['msg']='操作失败：'.$data['errmsg'].',errcode:'.$data['errcode'];
			return $dataFailure;
		}
		$dataSuccess['data']=$data;
		return $dataSuccess;
	}

	/**
	 * 发送微信模板消息
	 * Author: shijy
	 * @param $content
	 * @return array|mixed
	 */
	public static function sendTemplateMsg($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=';
		return self::send($url,$content);
	}

	
	
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 根据open_id群发消息
	 * Author: shijy
	 * @param $content
	 * @return array
	 */
	private static function sendMass($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=';
		return self::send($url,$content);
	}


	/**
	 * 根据openids发送卡关
	 * Author: shijy
	 * @param $OpenIDs
	 * @param $cardId
	 * @return array|mixed
	 */
	public static function sendCardByOpenID($OpenIDs,$cardId){
		$data=array(
			'touser'=>(array)$OpenIDs,
			'wxcard'=>array('card_id'=>$cardId),
			"msgtype"=>"wxcard"
		);
		return self::sendMass(json_encode($data));
	}

	/**
	 * 根据openids发送文字信息
	 * Author: shijy
	 * @param $OpenIDs
	 * @param $text
	 * @return array|mixed
	 */
	public static function sendTextByOpenID($OpenIDs,$text){
		$data=array(
			'touser'=>(array)$OpenIDs,
			'text'=>array('content'=>$text),
			"msgtype"=>"text"
		);
		return self::sendMass(json_encode($data));
	}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 发送客服消息
	 * Author: shijy
	 * @param $content
	 * @return array
	 */
	private static function sendCustom($content){
		$url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=';
		return self::send($url,$content);
	}


	/**
	 * 获取卡券的cardExt数组
	 * Author: shijy
	 * @param $wxCardID  微信卡券编号
	 * @param $openID
	 * @param $code
	 * @return array
	 */
	public static function getCardExt($wxCardID,$openID='',$code=''){
		$cardApiTicket=self::getCardApiTicket();
		if($cardApiTicket['status']!=0){
			return $cardApiTicket;
		}
		$card_ticket=$cardApiTicket['data']['ticket'];
		$time=time().'';
		$nonceStr=self::createNonceStr();
		$tmpArr = array($card_ticket,$time,$wxCardID,$code,$openID,$nonceStr);

		sort($tmpArr, SORT_STRING);
		$tmpStr = implode( $tmpArr );
		$signature = sha1( $tmpStr );

		$CardExt=array(
			'card_id'	=> $wxCardID,
			'code'		=> $code,
			'openid'	=> $openID,
			'timestamp'	=> $time,
			'signature'	=> $signature,
			'nonce_str' => $nonceStr,
			'outer_id'	=> 1,
		);
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataSuccess['cardExt']		= json_encode($CardExt);
		$dataSuccess['wxCardId']	= $wxCardID;
		return $dataSuccess;
	}


	/**
	 * 通过客服消息发送卡券
	 * Author: shijy
	 * @param $openID
	 * @param $cardID
	 * @param $code
	 * @return array
	 */
	public static function sendCustom_card($openID,$cardID,$code){
		$cardExtReturn=self::getCardExt($cardID,$openID,$code);
		if($cardExtReturn['status']!=0){
			return $cardExtReturn;
		}
		$cardExt=$cardExtReturn['cardExt'];

		$data=array(
			'touser'=>$openID,
			'msgtype'=>'wxcard',
			'wxcard'=>array(
				'card_id' =>$cardID,
				'card_ext'=>$cardExt
			)
		);
		return self::sendCustom(json_encode($data));
	}

	/**
	 * 通过客服消息发送普通文字
	 * Author: shijy
	 * @param $openID
	 * @param $text
	 * @return array
	 */
	public static function sendCustom_text($openID,$text){
		$data=array(
			'touser'=>$openID,
			'msgtype'=>'text',
			'text'=>array(
				'content'=>$text
			)
		);
		return self::sendCustom(json_encode($data));
	}


	/**
	 *指查询用户信息（微信）
	 * Author: shijy
	 * @param $OpenIDs
	 * @return array|mixed
	 */
	public static function batchGetUser($OpenIDs){
		$data=array(
			'user_list'=>array()
		);
		foreach($OpenIDs as $one){
			$data['user_list'][]=array('openid'=>$one,'lang'=>'zh-CN');
		}
		$url='https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=';
		return self::send($url,json_encode($data));
	}
}